package pers.yurwisher.dota2.pudge.system.controller;

import cn.hutool.core.util.IdUtil;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pers.yurwisher.dota2.pudge.annotation.rest.AnonymousGetMapping;

import java.util.concurrent.TimeUnit;

/**
 *
 * @author yq
 * @date 2021/03/08 22:27
 * @since V1.0.0 redis 分布式锁测试
 * @description
 */
@RestController
@RequestMapping("/test")
public class TestController {

    private final static Logger logger = LoggerFactory.getLogger(TestController.class);

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private RedissonClient redisson;

    @AnonymousGetMapping("redissonLock")
    public String test() {
        String lockKey = "lockKey";
        String clientId = IdUtil.fastUUID();
        //加锁并添加过期时间
        Boolean haveGetLock = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 5, TimeUnit.SECONDS);
        if (!haveGetLock) {
            return "123";
        }
        try {
            int stock = (int) redisTemplate.opsForValue().get("stock");
            logger.info("当前库存:{}",stock);
            if(stock > 0) {
                int realStock = stock - 1;
                redisTemplate.opsForValue().set("stock",realStock);
                logger.info("扣减库存");
            }
        } finally {
            //释放锁 只能是此线程本身释放锁
            if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) {
                redisTemplate.delete(lockKey);
            }
        }
        return "end";
    }

    @AnonymousGetMapping("redissonLock2")
    public String test2() {
        String lockKey = "lockKey";
        RLock lock = redisson.getLock(lockKey);
        try {
            lock.lock();
            int stock = (int) redisTemplate.opsForValue().get("stock");
            logger.info("当前库存:{}",stock);
            if(stock > 0) {
                int realStock = stock - 1;
                redisTemplate.opsForValue().set("stock",realStock);
            }
        } finally {
            lock.unlock();
        }
        return "end";
    }
}
